/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package proy1sistdistribuidos.control.advertisements;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Enumeration;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.Document;
import net.jxta.document.Element;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory;
import net.jxta.document.StructuredDocumentUtils;
import net.jxta.document.StructuredTextDocument;
import net.jxta.document.TextElement;
import net.jxta.protocol.PipeAdvertisement;

/**
 * Clase AdvertisementContenidoFisico
 *
 * Clase que define un advertisement que contiene la informacion
 * asociada a un Contenido Fisico de una Imagen
 * @author Carlos Diaz Maya, Juan Felipe Garcia
 */
public class AdvertisementContenidoFisicoImpl extends AdvertisementContenidoFisico {
    private final static String mimeType= "text/xml";

    public final static String etiquetaNombreAdvertisement = "ContenidoFisico";

    public final static String etiquetaIdContenidoFisico = "IdContenido";

    public final static String etiquetaNombreArchivoFisico = "NombreArchivoFisico";

    public final static String etiquetaContenidoBase64 = "ContenidoBase64";

    public final static String etiquetaMimeTypeArchivoFisico = "TipoMime";
    /**
     * arreglo de elementos para indexar el advertisement
     */
    private final static String[] camposIndexados = {etiquetaIdContenidoFisico};

    public AdvertisementContenidoFisicoImpl(InputStream stream) throws IOException {
        super();

        StructuredTextDocument documentoEstructurado = (StructuredTextDocument) StructuredDocumentFactory.newStructuredDocument(new MimeMediaType(mimeType), stream);
        this.leerAdvertisement(documentoEstructurado);
    }

    public AdvertisementContenidoFisicoImpl(Element documentoEstructurado) {
        super();
        this.leerAdvertisement((TextElement) documentoEstructurado);
    }

    public AdvertisementContenidoFisicoImpl(){
        super();
    }

   private void leerAdvertisement(TextElement documentoEstructurado) throws IllegalArgumentException {
        if(documentoEstructurado.getName().equals(getTipoAdvertisement())) {
            Enumeration elementos = documentoEstructurado.getChildren();
            while(elementos.hasMoreElements()) {
                TextElement elemento = (TextElement) elementos.nextElement();

                if(elemento.getName().equals(PipeAdvertisement.getAdvertisementType())) {
                    PipeAdvertisement pipe = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(elemento);
                    setPipeAdvertisement(pipe);
                    continue;
                }
                if(elemento.getName().equals(etiquetaNombreAdvertisement)) {
                    this.setNombreAdvertisement(elemento.getTextValue());
                    continue;
                }
                if(elemento.getName().equals(etiquetaIdContenidoFisico)) {
                    this.setIdContenidoFisico(elemento.getTextValue());
                    continue;
                }
                if(elemento.getName().equals(etiquetaNombreArchivoFisico)) {
                    this.setNombreArchivoFisico(elemento.getTextValue());
                    continue;
                }
                if(elemento.getName().equals(etiquetaMimeTypeArchivoFisico)){
                    this.setMimeTypeArchivoFisico(elemento.getTextValue());
                }

                if(elemento.getName().equals(etiquetaContenidoBase64)) {
                    this.setContenidoBase64(elemento.getTextValue());
                    continue;
                }
            }
        } else {
            throw new IllegalArgumentException("El tipo de advertisement no tiene la estructura esperada");
        }

   }


    @Override
    public Document getDocument(MimeMediaType mmt) throws IllegalArgumentException {
               if((null!= getNombreAdvertisement()) && (null!= this.getPipeAdvertisement()))
        {
            StructuredDocument documento= (StructuredDocument) StructuredDocumentFactory.newStructuredDocument(mmt, getAdvertisementType());
            Element element;

            element= documento.createElement(etiquetaIdContenidoFisico, this.getIdContenidoFisico());
            documento.appendChild(element);

            element= documento.createElement(etiquetaNombreAdvertisement, this.getNombreAdvertisement());
            documento.appendChild(element);

            element= documento.createElement(etiquetaNombreArchivoFisico, this.getNombreArchivoFisico());
            documento.appendChild(element);

            element= documento.createElement(etiquetaMimeTypeArchivoFisico, this.getMimeTypeArchivoFisico());
            documento.appendChild(element);

            element= documento.createElement(etiquetaContenidoBase64, this.getContenidoBase64());
            documento.appendChild(element);

            PipeAdvertisement pipe = getPipeAdvertisement();
            if(pipe!=null){
                StructuredTextDocument advDoc = (StructuredTextDocument) pipe.getDocument(mmt);
                StructuredDocumentUtils.copyElements(documento, documento, advDoc);
            }
            return documento;
        }
        else{
            throw new IllegalArgumentException("faltan datos para hacer advert");
        }
    }

    @Override
    public String[] getIndexFields() {
        return this.camposIndexados;
    }

    public String toString()
    {
        try {
            StringWriter out = new StringWriter();
            StructuredTextDocument doc = (StructuredTextDocument) getDocument(new MimeMediaType(mimeType));
            doc.sendToWriter(out);
            return out.toString();
        } catch (IOException ex) {
            System.out.println("====== ERROR ======");
            System.out.println(ex.getMessage());
            return "";
        }
    }

    public static class Instantiator implements AdvertisementFactory.Instantiator{

        public String getAdvertisementType() {
           return AdvertisementContenidoFisico.getAdvertisementType();
        }

        public Advertisement newInstance() {
            return new AdvertisementContenidoFisicoImpl();
        }

        public Advertisement newInstance(Element root) {
            return new AdvertisementContenidoFisicoImpl(root);
        }

    };
}
